/**
 * @author huangbo
 * �������ڣ�2011Aug 24, 2011
 * TODO// N/A
 */
package com.platform.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

import com.platform.bean.PageBean;

public class BaseDao {

	private static final SessionFactory sessionFactory = buildSessionFactory();

    private static SessionFactory buildSessionFactory() {
        try {
            // Create the SessionFactory from hibernate.cfg.xml
            return new Configuration().configure().buildSessionFactory();
        }
        catch (Throwable ex) {
            // Make sure you log the exception, as it might be swallowed
            System.err.println("Initial SessionFactory creation failed." + ex);
            throw new ExceptionInInitializerError(ex);
        }
    }

    public static SessionFactory getSessionFactory() {
        return sessionFactory;
    }
	
	/**
	 * 
	 */
	public BaseDao() {
		super();
	}

	private static String resetSql(String sql) {
		String ret = "";
		String s = sql;
		s = s.replaceAll("( )(F|f)(R|r)(O|o)(M|m)( )", " FROM ");
		s = s.replaceAll("( )(S|s)(E|e)(L|l)(E|e)(C|c)(T|t)( )", " SELECT ");
		s = s.replaceAll("( )(O|o)(R|r)(D|d)(E|e)(R|r)( )(B|b)(Y|y)( )", " ORDER BY ");
		int indexFrom = s.indexOf("FROM");
		while (s.indexOf("FROM") >= 0) {
			indexFrom = indexFrom + 4;
			String s1 = s.substring(0, indexFrom);
			s = s.substring(indexFrom);
			int indexWhere = s1.indexOf("WHERE");
			if (indexWhere > 0) {
				indexWhere = indexWhere + 5;
				s1 = s1.substring(0, indexWhere) + s1.substring(indexWhere).replace("WHERE", "AND");
			}
			ret += s1;
			indexFrom = s.indexOf("FROM");
		}
		int indexWhere = s.indexOf("WHERE");
		if (indexWhere > 0) {
			indexWhere = indexWhere + 5;
			s = s.substring(0, indexWhere) + s.substring(indexWhere).replace("WHERE", "AND");
		}
		ret += s;
		return ret;
	}

	/** 新增一条数据到表.
	 * @param  Object obj   	待新增hibernate对象
	 * @return boolean
	 */
	public static boolean add(Object obj) {
//		obj=DbUtil.resetObject(obj);
		Session session = null;
		Transaction tx = null;
	    try {
			session = sessionFactory.openSession();
	    	tx = session.beginTransaction();
	      	session.save(obj);
	      	tx.commit();
	      	return true;
	    } catch (Exception e) {
	    	e.printStackTrace();
	    	if (tx != null) {
	    		try {
	    			tx.rollback();
	    		} catch (Exception ex) {
	    			ex.printStackTrace();
	    			return false;
	    		}
	      	}
	      	return false;
	    } finally {
	    	session.close();
	    }
	}

	/**	从表中删除一条数据.
	 * @param  Object obj   	待删除的hibernate对象
	 * @return boolean
	 */
	public static boolean delete(Object obj) {
//		obj=DbUtil.resetObject(obj);
		Session session = null;
		Transaction tx = null;
		try {
			session =sessionFactory.openSession();
			tx = session.beginTransaction();
			session.delete(obj);
			tx.commit();
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			if (tx != null) {
	    		try {
	    			tx.rollback();
	    		} catch (Exception ex) {
	    			ex.printStackTrace();
	    			return false;
	    		}
			}
			return false;
		} finally {
			session.close();
		}
	}

	/** 更新表中的一条数据.
	 * @param	Object obj	  待修改的hibernate对象
	 * @return boolean
	 */
	public static boolean update(Object obj) {
//		obj=DbUtil.resetObject(obj);
		Session session = null;
		Transaction tx = null;
		try {
			session =sessionFactory.openSession();
			tx = session.beginTransaction();
			session.update(obj);
			tx.commit();
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			if (tx != null) {
	    		try {
	    			tx.rollback();
	    		} catch (Exception ex) {
	    			ex.printStackTrace();
	    			return false;
	    		}
			}
			return false;
		} finally {
			session.close();
		}
	}

	/** 通过SQL语句从数据库中取出单条记录.
	 * @param sql 完整的SQL语句
	 * @return List
	 */
	public static Object getUniqueResult(String sql) {
		sql = resetSql(sql);
		Session session = null;
		try {
			session =sessionFactory.openSession();
			Query query = session.createQuery(sql);
			Object obj = query.uniqueResult();
			if(obj!=null){
			}
			return obj;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		} finally {
			session.close();
		}
	}

	//从结果集中取一条数据
	public static  Object getUniqueResultFromSet(String sql) {
		sql = resetSql(sql);
		Session session = null;
		try {
			session =sessionFactory.openSession();
			Query query = session.createQuery(sql);
			query.setMaxResults(1);
			Object obj = query.uniqueResult();
			return obj;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		} finally {
			session.close();
		}
	}
	
	public static Object getUniqueResultFromSet(String sql, List param) {
		sql = resetSql(sql);
//		if(param.size()>0){
//			param=DbUtil.resetParam(param);
//			}
		Session session = null;
		try {
			session =sessionFactory.openSession();
			Query query = session.createQuery(sql);
			query.setMaxResults(1);
			for (int i = 0; i < param.size(); i++) {
				query.setParameter(i, param.get(i));
			}
			Object obj = query.uniqueResult();
			return obj;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		} finally {
			session.close();
		}
	}

	
	/** 通过SQL语句与ParamList从数据库中取出单条记录.
	 * @param sql 完整的SQL语句
	 * @param param 输入参数，取代SQL语句中的"?"
	 * @return List
	 */
	public static Object getUniqueResult(String sql, List param) {
		sql = resetSql(sql);
//		if(param.size()>0){
//			param=DbUtil.resetParam(param);
//			}
		Session session = null;
		try {
			session =sessionFactory.openSession();
			Query query = session.createQuery(sql);
			for (int i = 0; i < param.size(); i++) {
				query.setParameter(i, param.get(i));
			}
			Object obj = query.uniqueResult();
			return obj;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		} finally {
			session.close();
		}
	}

	/** 通过SQL语句从数据库中取出全部记录.
	 * @param sql 完整的SQL语句
	 * @return List
	 */
	public static List getList(String sql) {
		Session session = null;
		try {
			session =sessionFactory.openSession();
			Query query = session.createQuery(sql);
			List list = query.list();
			return list;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		} finally {
			session.close();
		}
	}
	/** 通过SQL与ParamList从数据库中取出全部记录.
	 * @param sql 完整的SQL语句
	 * @param param SQL查询条件参数 代替Sql中的"?"
	 * @return List
	 */

	public static List getList(String sql, List param) {
		sql = resetSql(sql);
//		if(param.size()>0){
//		param=DbUtil.resetParam(param);
//		}
		Session session = null;
		try {
			session =sessionFactory.openSession();
			Query query = session.createQuery(sql);
			for (int i = 0; i < param.size(); i++) {
				query.setParameter(i, param.get(i));
			}
			List list = query.list();
			return list;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		} finally {
			session.close();
		}
	}

	/** 通过SQL语句从数据库中取出部分记录.
	 * @param first 首记录
	 * @param size 列表长度
	 * @param sql 完整的SQL语句
	 * @return List
	 */
	public static List getList(int first, int size, String sql) {
		sql = resetSql(sql);
		Session session = null;
		try {
			session =sessionFactory.openSession();
			Query query = session.createQuery(sql);
			query.setFirstResult(first - 1);
			query.setMaxResults(size);
			List list = query.list();
			return list;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		} finally {
			session.close();
		}
	}

	/** 通过SQL与ParamList从数据库中取出部分记录 分页显示.
	 * @param first 首记录
	 * @param size 列表长度
	 * @param sql 完整的SQL语句
	 * @param param SQL查询条件参数,代替Sql中的"?"
	 * @return List
	 */
	public static List getList(int first, int size, String sql, List param) {
		sql = resetSql(sql);
//		if(param.size()>0){
//			param=DbUtil.resetParam(param);
//			}
		Session session = null;
		try {
			session =sessionFactory.openSession();
			Query query = session.createQuery(sql);
			for (int i = 0; i < param.size(); i++) {
				query.setParameter(i, param.get(i));
			}
			query.setFirstResult(first - 1);
			query.setMaxResults(size);
			List list = query.list();
			return list;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		} finally {
			session.close();
		}
	}

	/** 通过SQL语句从数据库中取出记录.
	 * @param nowPage 当前页
	 * @param pageSize 列表长度 为0时表示取全部记录
	 * @param sql 完整的SQL语句
	 * @return Object[] = PageSplitBean + List
	 */
	public static Object[] getSpiltList(int nowPage, int pageSize, String sql) {
		
		sql = resetSql(sql);
		Session session = null;
		try {
			session =sessionFactory.openSession();
			Query query = session.createQuery(sql);
			int first = 0;
			Object[] obj = new Object[2];
			PageBean bean = new PageBean();;
			if (pageSize > 0) {
				if (nowPage > 0) {
					String countSql = sql;
					int beginIndex; 
					int endIndex;
					if (countSql.indexOf("SELECT") == -1) {
						countSql = "SELECT COUNT(*) " + countSql;
					} else {
						beginIndex = countSql.indexOf("FROM");
						countSql = "SELECT COUNT(*) " + countSql.substring(beginIndex);
					}
					endIndex = countSql.indexOf("ORDER BY");
					if (endIndex > 0) {
						countSql = countSql.substring(0, endIndex);
					}
					first = (nowPage - 1) * pageSize;
					
					Query  countQuery = session.createQuery(countSql);
					int totalCount = ((Long) countQuery.uniqueResult()).intValue();
					int totalPage = totalCount / pageSize;
					totalPage = (totalCount % pageSize == 0) ? totalPage : totalPage + 1;
					bean.setCurrPage(nowPage);
					bean.setTotalPage(totalPage);
					bean.setPageSize(totalCount);
				}
				query.setFirstResult(first);
				query.setMaxResults(pageSize);
			}
			List list = query.list();
			obj[0] = bean;
			obj[1] = list;
			return obj;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		} finally {
			session.close();
		}
	}
	
	/** 通过SQL与ParamList从数据库中取出记录.
	 * @param nowPage 当前页
	 * @param pageSize 列表长度 为0时表示取全部记录
	 * @param sql 完整的SQL语句
	 * @param param SQL查询条件参数,代替Sql中的"?"
	 * @return Object[] = PageSplitBean + List
	 */
	public static Object[] getSpiltList(int nowPage, int pageSize, String sql, List param) {
		sql = resetSql(sql);
//		if(param.size()>0){
//		param=DbUtil.resetParam(param);
//		}
		Session session = null;
		try {
			session =sessionFactory.openSession();
			Query query = session.createQuery(sql);
			for (int i = 0; i < param.size(); i++) {
				query.setParameter(i, param.get(i));
			}
			int first = 0;
			Object[] obj = new Object[2];
			PageBean bean = null;
			if (nowPage > 0) {
				String countSql = sql;
				int beginIndex;
				int endIndex;
				if (countSql.indexOf("SELECT") == -1) {
					countSql = "SELECT COUNT(*) " + countSql;
				} else {
					beginIndex = countSql.indexOf("FROM");
					countSql = "SELECT COUNT(*) " + countSql.substring(beginIndex);
				}
				endIndex = countSql.indexOf("ORDER BY");
				if (endIndex > 0) {
					countSql = countSql.substring(0, endIndex);
				}
				
				first = (nowPage - 1) * pageSize;
				Query  countQuery = session.createQuery(countSql);
				for (int i = 0; i < param.size(); i++) {
					countQuery.setParameter(i, param.get(i));
				}
				int totalCount = ((Long) countQuery.uniqueResult()).intValue();
				int totalPage = totalCount / pageSize;
				totalPage = (totalCount % pageSize == 0) ? totalPage : totalPage + 1;
				bean = new PageBean();
				bean.setCurrPage(nowPage);
				bean.setTotalPage(totalPage);
				bean.setPageSize(totalCount);
			}
			if (pageSize > 0) {
				query.setFirstResult(first);
				query.setMaxResults(pageSize);
			}
			for (int i = 0; i < param.size(); i++) {
				query.setParameter(i, param.get(i));
			}
			List list = query.list();
			obj[0] = bean;
			obj[1] = list;
			return obj;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		} finally {
			session.close();
		}
	}
	
	
	/** 事务处理.
	 * @param insertList		增加的数据列表
	 * @param updateList		更新的数据列表
	 * @param deleteList		删除的数据列表
	 * @return boolean
	 */

	public static boolean batchTransaction(List insertList, List updateList, List deleteList) {
		Session session = null;
		Transaction tx = null;
		try {
			session =sessionFactory.openSession();
			tx = session.beginTransaction();
			if (deleteList != null && deleteList.size() > 0) {
				for (int i = 0; i < deleteList.size(); i++) {
					session.delete(deleteList.get(i));
				}
			}
			if (insertList != null && insertList.size() > 0) {
				for (int i = 0; i < insertList.size(); i++) {
					session.save(insertList.get(i));
				}
			}
			if (updateList != null && updateList.size() > 0) {
				for (int i = 0; i < updateList.size(); i++) {
					session.update(updateList.get(i));
				}
			}
			tx.commit();
			return true;
		} catch (Exception e) {
	    	e.printStackTrace();
	    	if (tx != null) {
	    		try {
	    			tx.rollback();
	    		} catch (Exception ex) {
	    			ex.printStackTrace();
	    			return false;
	    		}
	      	}
	      	return false;
		} finally {
			session.close();
		}
	}

	/** 取序列的下一个值.
	 * @param strSequence 序列名称
	 * @return Long
	 */
	public static Long getSequence(String strSequence) {
		String sql = "select " + strSequence + ".Nextval from dual";
		sql=resetSql(sql);
		Session session = null;
		Transaction tx = null;
		Connection con = null;
		PreparedStatement cstmt = null;
		try {
			session =sessionFactory.openSession();
			tx = session.beginTransaction();
			con = session.connection();
			cstmt = con.prepareStatement(sql);
			ResultSet rs = cstmt.executeQuery();
			rs.next();
			long sequence = rs.getLong(1);
			tx.commit();
			con.close();
			return new Long(sequence);
		} catch (Exception e) {
			if (tx != null) {
				tx.rollback();
			}
			e.printStackTrace();
			return null;
		} finally {
			session.close();
		}
	}

	/** 执行SQL语句.
	 * @param sql 序列名称
	 * @return boolean
	 */
	public static boolean executeSql(String sql) {
		Session session = null;
		Transaction tx = null;
		Connection con = null;
		Statement cstmt = null;
		try {
			session =sessionFactory.openSession();
			tx = session.beginTransaction();
			con = session.connection();
//			cstmt = con.prepareStatement(sql);
//			cstmt.executeQuery();
			cstmt = con.createStatement();
			cstmt.execute(sql);
//			cstmt.executeUpdate(sql);
			tx.commit();
			con.close();
			return true;
		} catch (Exception e) {
	    	e.printStackTrace();
	    	if (tx != null) {
	    		try {
	    			tx.rollback();
	    		} catch (Exception ex) {
	    			ex.printStackTrace();
	    			return false;
	    		}
	      	}
	      	return false;
		}finally {
			session.close();
		}
	}
	
	
	/**
	 * 直接使用orcal数据库sql语句，i：返回结果的列数
	 * 
	 * @param sql
	 * @param i
	 * @return
	 */
	public static List getSql(String sql, int i)
	{
		Session session = null;
		Connection con = null;
		Transaction tx = null;
		PreparedStatement cstmt = null;
		try
		{
			session =sessionFactory.openSession();
			tx = session.beginTransaction();
			con = session.connection();
			cstmt = con.prepareStatement(sql, ResultSet.TYPE_SCROLL_SENSITIVE,
			        ResultSet.CONCUR_UPDATABLE);
			ResultSet set = cstmt.executeQuery();
			List list = new ArrayList();
			while (set.next())
			{
				Object[] oj = new Object[i];
				for (int j = 1; j <= oj.length; j++)
				{
					oj[j - 1] = set.getObject(j);
				}
				list.add(oj);
			}
			tx.commit();
			cstmt.close();
			if (con != null)
			{
				con = null;
			}
			return list;
		} catch (Exception e)
		{
			e.printStackTrace();
			return null;
		} finally
		{
			session.close();
		}
	}

	
	
	public static Object getById(Long id,Class classname){
		Session session = null;
		Object obj =null;
		try {
			session =sessionFactory.openSession();
			 obj = session.get(classname, id);
			
			
		} catch (Exception e) {
			e.printStackTrace();
			
		} finally {
			session.close();
		}
		
		return obj;
	}
	
	
	//批量插入
	public static boolean batchSave(List list){
		Session session = null;
		Transaction tx = null;
	    try {
			session =sessionFactory.openSession();
	    	tx = session.beginTransaction();
	    	for (int i = 0; i < list.size(); i++) {
	    		Object obj = list.get(i); 
	    	    session.save(obj); 
	    	    if ( i % 20 == 0 ) { 
	    	      //20，与JDBC批量设置相同 
	    	       //将本批插入的对象立即写入数据库并释放内存 
	    	        session.flush(); 
	    	       session.clear(); 
	    	    } 
			}
	      	tx.commit();
	      	return true;
	    } catch (Exception e) {
	    	e.printStackTrace();
	    	if (tx != null) {
	    		try {
	    			tx.rollback();
	    		} catch (Exception ex) {
	    			ex.printStackTrace();
	    			return false;
	    		}
	      	}
	      	return false;
	    } finally {
	    	session.close();
	    }
	}
	
	//批量插入
	public static boolean batchUpdate(List list){
		Session session = null;
		Transaction tx = null;
	    try {
			session =sessionFactory.openSession();
	    	tx = session.beginTransaction();
	    	for (int i = 0; i < list.size(); i++) {
	    		Object obj = list.get(i); 
	    	    session.update(obj); 
	    	    if ( i % 20 == 0 ) { 
	    	      //20，与JDBC批量设置相同 
	    	       //将本批插入的对象立即写入数据库并释放内存 
	    	        session.flush(); 
	    	       session.clear(); 
	    	    } 
			}
	      	tx.commit();
	      	return true;
	    } catch (Exception e) {
	    	e.printStackTrace();
	    	if (tx != null) {
	    		try {
	    			tx.rollback();
	    		} catch (Exception ex) {
	    			ex.printStackTrace();
	    			return false;
	    		}
	      	}
	      	return false;
	    } finally {
	    	session.close();
	    }
	}
	

}
